package middleware

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sync"

	"github.com/ammyhaber/seckill/pkg/breaker"
	"github.com/ammyhaber/seckill/pkg/limiter"
)

// ResponseWriter包装器，用于捕获响应状态
type ResponseWriterWrapper struct {
	http.ResponseWriter
	Status      int
	wroteHeader bool
}

// NewResponseWriterWrapper 创建ResponseWriter包装器
func NewResponseWriterWrapper(w http.ResponseWriter) *ResponseWriterWrapper {
	return &ResponseWriterWrapper{ResponseWriter: w}
}

// WriteHeader 重写WriteHeader方法，记录状态码
func (rw *ResponseWriterWrapper) WriteHeader(code int) {
	if !rw.wroteHeader {
		rw.Status = code
		rw.wroteHeader = true
		rw.ResponseWriter.WriteHeader(code)
	}
}

// Write 重写Write方法，确保状态码被记录
func (rw *ResponseWriterWrapper) Write(b []byte) (int, error) {
	if !rw.wroteHeader {
		rw.WriteHeader(http.StatusOK)
	}
	return rw.ResponseWriter.Write(b)
}

// StatusCode 返回响应状态码
func (rw *ResponseWriterWrapper) StatusCode() int {
	if rw.Status == 0 {
		return http.StatusOK
	}
	return rw.Status
}

// RateLimiterMiddleware 限流中间件
func RateLimiterMiddleware(limiter limiter.RateLimiter) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// 前置：判断是否允许请求通过
			if !limiter.Allow() {
				w.Header().Set("Content-Type", "application/json")
				w.WriteHeader(http.StatusTooManyRequests)
				json.NewEncoder(w).Encode(map[string]string{
					"status":  "error",
					"message": "请求频率过高，请稍后再试",
				})
				return
			}
			// 请求通过，继续处理
			next.ServeHTTP(w, r)
		})
	}
}

// CircuitBreakerMiddleware 熔断器中间件
func CircuitBreakerMiddleware(circuitBreaker *BreakerAdapter, serviceName string) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// 前置：检查熔断器状态
			if circuitBreaker.GetState() == breaker.StateOpen {
				w.Header().Set("Content-Type", "application/json")
				w.WriteHeader(http.StatusServiceUnavailable)
				json.NewEncoder(w).Encode(map[string]string{
					"status":  "error",
					"message": "服务暂时不可用，请稍后再试",
				})
				return
			}

			// 包装ResponseWriter以捕获状态码
			ww := NewResponseWriterWrapper(w)

			// 执行请求
			next.ServeHTTP(ww, r)

			// 后置：根据响应状态更新熔断器
			if ww.Status >= 500 {
				circuitBreaker.Execute(func() error {
					return fmt.Errorf("服务错误: %d", ww.Status)
				})
			} else {
				circuitBreaker.Execute(func() error {
					return nil // 成功
				})
			}
		})
	}
}

// PathRateLimiterMiddleware 基于路径的限流中间件
func PathRateLimiterMiddleware(limiters map[string]limiter.RateLimiter) func(http.Handler) http.Handler {
	var mu sync.RWMutex

	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			path := r.URL.Path

			// 获取对应路径的限流器
			mu.RLock()
			limiter, exists := limiters[path]
			mu.RUnlock()

			if exists {
				if !limiter.Allow() {
					w.Header().Set("Content-Type", "application/json")
					w.WriteHeader(http.StatusTooManyRequests)
					json.NewEncoder(w).Encode(map[string]string{
						"status":  "error",
						"message": "该接口请求频率过高，请稍后再试",
					})
					return
				}
			}

			// 请求通过，继续处理
			next.ServeHTTP(w, r)
		})
	}
}

// BreakerManager 全局熔断器管理器单例
var (
	breakerManager     *breaker.BreakerManager
	breakerManagerOnce sync.Once
)

// GetBreakerManager 获取全局熔断器管理器实例
func GetBreakerManager() *breaker.BreakerManager {
	breakerManagerOnce.Do(func() {
		breakerManager = breaker.NewBreakerManager()
	})
	return breakerManager
}
